package cc.rengu.igas.channel.ncqs.core.realize.impl;

import cc.rengu.igas.channel.ncqs.common.constant.NcqsConfigConstant;
import cc.rengu.igas.channel.ncqs.common.constant.NcqsParamConstant;
import cc.rengu.igas.channel.ncqs.common.constant.NcqsServiceConstant;
import cc.rengu.igas.channel.ncqs.common.constant.NcqsTreeNodeConstant;
import cc.rengu.igas.channel.ncqs.common.enums.RespCodeEnum;
import cc.rengu.igas.channel.ncqs.core.model.request.*;
import cc.rengu.igas.channel.ncqs.core.model.response.*;
import cc.rengu.igas.channel.ncqs.core.realize.NcqsService;
import cc.rengu.jradp.schedule.Schedule;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.CertInfoMapper;
import cc.rengu.oltp.service.common.dao.DstChannelInfoMapper;
import cc.rengu.oltp.service.common.dao.SecPlanInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.CertInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.DstChannelInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.SecPlanInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.CertInfo;
import cc.rengu.oltp.service.common.entity.DstChannelInfo;
import cc.rengu.oltp.service.common.entity.SecPlanInfo;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.utility.util.AmountUtil;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.XmlConfigUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.base.TimeUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSON;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class NcqsServiceImpl implements NcqsService {

    RgLogger rglog = RgLog.getLogger(this.getClass().getName());
    //原交易类型（系统内部交易码）
    private String origTxnType;

    public NcqsServiceImpl() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        origTxnType = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_NUM);
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        /* 获取通道配置信息 */
        DstChannelInfoMapper dstChannelInfoMapper = new DstChannelInfoMapperImpl();
        DstChannelInfo dstChannelInfo = dstChannelInfoMapper.selectDstChannelInfoByPrimaryKey(instId, NcqsParamConstant.TUNL_ID_NCQS);
        if (null == dstChannelInfo) {
            rglog.error("获取通道<{}>配置信息失败!", NcqsParamConstant.TUNL_ID_NCQS);
            throw new BizException(RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespCode(), RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespDesc());
        }
       /* //第一位代表发卡侧状态，第二位代表侧受理状态
        char[] sysStatus = sysInfo.getSysStatus().toCharArray();
        //增加判断受理侧是否签到
        if (ChannelStatusEnum.ABNORMAL.getStatus().equals(String.valueOf(sysStatus[1]))) {
            if (!"M00SH501".equals(origTxnType)) {
                //非签到交易，状态异常
                rglog.error("通道<{}>配置信息，系统状态异常：<{}>,请先进行签到！",NcqsParamConstant.TUNL_ID_NCQS, sysInfo.getSysStatus());
                throw new BizException(RespCodeEnum.CHANNEL_STATUS_UNNORMAL.getRespCode(), RespCodeEnum.CHANNEL_STATUS_UNNORMAL.getRespDesc());
            }
        }*/

        //报文头必填属性赋值
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_MSG_VER, XmlConfigUtil.getXmlConfigCacheKeyValue(NcqsConfigConstant.NCQS_CONF_NODE, NcqsConfigConstant.NCQS_VERSION));
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_ISSR_ID, XmlConfigUtil.getXmlConfigCacheKeyValue(NcqsConfigConstant.NCQS_CONF_NODE, NcqsConfigConstant.NCQS_ISSR_ID));
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_SEND_ISSR_ID, XmlConfigUtil.getXmlConfigCacheKeyValue(NcqsConfigConstant.NCQS_CONF_NODE, NcqsConfigConstant.NCQS_ISSR_ID));
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_SEND_ACCT_ISSR_ID, XmlConfigUtil.getXmlConfigCacheKeyValue(NcqsConfigConstant.NCQS_CONF_NODE, NcqsConfigConstant.NCQS_ACCT_ISSR_ID));

        String dateTime;
        /*报文头部分字段赋值*/
        /* 报文方向 (请求报文/通知报文-11，应答报文-12)*/
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_DRCTN, "11");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_ISSR_ID, XmlConfigUtil.getXmlConfigCacheKeyValue(NcqsConfigConstant.NCQS_CONF_NODE, NcqsConfigConstant.NCQS_ISSR_ID));
        //设置日期时间,从系统流水号获取,撤销，退款从原流水号获取原时间
        //流水号规则：8位渠道标识 + 8位日期 + 6位时间 + 2位服务器集群标识 + 2位预留位 + 6位序号
        String seqNo = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        if (seqNo == null) {
            dateTime = TimeUtil.getDateTime("yyyyMMddHHmmss");
        } else {
            dateTime = seqNo.substring(8, 22);//日期从流水号截取
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = dateFormat.parse(dateTime, pos);
        String dateStr = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(strtodate);
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_SND_DT, dateStr);

        /* 根据通道安全计划获取安全计划 */
        SecPlanInfoMapper secPlanInfoMapper = new SecPlanInfoMapperImpl();
        List<SecPlanInfo> secPlanInfoList = secPlanInfoMapper.selectSecPlanInfoBySecPlanId(instId, dstChannelInfo.getSecPlanId());
        if (null != secPlanInfoList && !secPlanInfoList.isEmpty()) {
            //过滤状态失效的数据
            secPlanInfoList = secPlanInfoList.stream().filter(item -> "Y".equals(item.getSecPlanStatus())).collect(Collectors.toList());
            xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.SEC_PLAN_INFO_LIST, JSON.toJSONString(secPlanInfoList));
            /* 加签证书 */
            Optional<SecPlanInfo> secPlanInfoOpt = secPlanInfoList.stream().filter(item -> item.getSecPlanType().equals(NcqsParamConstant.SIGN_CERT_TYPE)).findFirst();
            if (secPlanInfoOpt.isPresent()) {
                CertInfoMapper certInfoMapper = new CertInfoMapperImpl();
                //todo 是否需要根据 CERT_INDEX + 证书类型 查询？ 待确认
                CertInfo certInfo = certInfoMapper.selectCertInfoByPrimaryKey(secPlanInfoOpt.get().getSecPlanId() + secPlanInfoOpt.get().getSecPlanType());
                if (null == certInfo) {
                    rglog.error("查询银联无卡快捷支付签名证书为空！交易结束！");
                    throw new BizException(RespCodeEnum.GET_KEY_INFO_ERROR.getRespCode(), RespCodeEnum.GET_KEY_INFO_ERROR.getRespDesc());
                }
                //设置签名的证书序列号
                xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_SIGN_SN, certInfo.getCertId());
                xmlTreeUtil.setXmlTreeObjectValue(NcqsTreeNodeConstant.NCQS_PRIVATE_CER_INFO, certInfo);
            }
        }


    }

    @Override
    public InstManageResponse instSignIn(InstManageRequest instManageRequest) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(instManageRequest);
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "4002");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_TYP, "4002"); //签到

        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡快捷机构签到服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        InstManageResponse response = new InstManageResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public InstManageResponse instSignOut(InstManageRequest instManageRequest) throws Exception {
        Schedule schedule = new Schedule();
        ConvertUtil.convertInput(instManageRequest);
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "4001");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_TYP, "4001"); //签退

        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡快捷机构签退服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        InstManageResponse response = new InstManageResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public AgreePaySignWithSmsAcqResponse agreePaySignWithSms(AgreePaySignWithSmsAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "0001");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_TYP, "0001"); //协议支付触发短信签约

        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联协议支付签约触发短信服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        AgreePaySignWithSmsAcqResponse response = new AgreePaySignWithSmsAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public ApplyPaySmsAcqResponse applyPaySms(ApplyPaySmsAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "0003");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_AMT, request.getTransCcy() + AmountUtil.changeF2Y(request.getTransAmt()));
        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡快捷直接支付签约触发短信服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        ApplyPaySmsAcqResponse response = new ApplyPaySmsAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public AcctVerifyAcqResponse acctVerify(AcctVerifyAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "0101");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_TYP, "0101"); //账户信息认证

        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡快捷账户信息验证服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        AcctVerifyAcqResponse response = new AcctVerifyAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public DebitAcctSignWithSmsAcqResponse debitAcctSignWithSms(DebitAcctSignWithSmsAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "0002");  //借记支付签约触发短信

        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡快捷借记支付签约触发短信服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        DebitAcctSignWithSmsAcqResponse response = new DebitAcctSignWithSmsAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public AgreePaySignAcqResponse agreePaySign(AgreePaySignAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "0201");

        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡快捷借记支付签约触发短信服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        AgreePaySignAcqResponse response = new AgreePaySignAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public DebitAcctSignAcqResponse debitAcctSign(DebitAcctSignAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "0202");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_TYP, "0202"); //借记转账签约
//        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_SEND_ACCT_ISSR_ID, request.getSderAcctIssrId()); //发起方账户所属机构标识

        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡快捷借记支付签约触发短信服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        DebitAcctSignAcqResponse response = new DebitAcctSignAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public AgreePaySignRescindAcqResponse agreePaySignRescind(AgreePaySignRescindAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "0301");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_TYP, "0301");
        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡支付协议支付解约服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }
        AgreePaySignRescindAcqResponse response = new AgreePaySignRescindAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public DebitAcctSignRescindAcqResponse debitAcctSignRescind(DebitAcctSignRescindAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "0302");
        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡支付协议支付解约服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }
        DebitAcctSignRescindAcqResponse response = new DebitAcctSignRescindAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public AgreePayAcqResponse agreePay(AgreePayAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        ConvertUtil.convertInput(request.getResfdInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "1001");
        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡支付协议支付服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }
        AgreePayAcqResponse response = new AgreePayAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public DirectPayAcqResponse directPay(DirectPayAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        ConvertUtil.convertInput(request.getResfdInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "1002");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_TYP, "1002");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_AMT, request.getTransCcy() + AmountUtil.changeF2Y(request.getTransAmt()));
        xmlTreeUtil.setXmlTreeStringValue("payeeIssrId", request.getPayeeAcctIssrId());
        xmlTreeUtil.setXmlTreeStringValue("payerAuthMsg", request.getAuthMsg());
        xmlTreeUtil.setXmlTreeStringValue("payerSmskey", request.getSmsKey());
        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡支付直接支付服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }
        DirectPayAcqResponse response = new DirectPayAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public DebitTransferAcqResponse debitTransfer(DebitTransferAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "1003");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_TYP, "1003");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_AMT, request.getTransCcy() + AmountUtil.changeF2Y(request.getTransAmt()));
        //发送机构标识为本行
        xmlTreeUtil.setXmlTreeStringValue("payeeIssrId", XmlConfigUtil.getXmlConfigCacheKeyValue(NcqsConfigConstant.NCQS_CONF_NODE, NcqsConfigConstant.NCQS_ACCT_ISSR_ID));

        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡支付借记转账服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }
        DebitTransferAcqResponse response = new DebitTransferAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public CreditPayAcqResponse creditPay(CreditPayAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        ConvertUtil.convertInput(request.getResfdInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "2001");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_AMT, request.getTransCcy() + AmountUtil.changeF2Y(request.getTransAmt()));
        //发送机构标识为本行
        xmlTreeUtil.setXmlTreeStringValue("payerIssrId", XmlConfigUtil.getXmlConfigCacheKeyValue(NcqsConfigConstant.NCQS_CONF_NODE, NcqsConfigConstant.NCQS_ACCT_ISSR_ID));


        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡支付退款服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }
        CreditPayAcqResponse response = new CreditPayAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public RefundAcqResponse refund(RefundAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        ConvertUtil.convertInput(request.getResfdInfo());
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "1101");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_TYP, "1101");
        //发送机构标识
        xmlTreeUtil.setXmlTreeStringValue("payerIssrId", XmlConfigUtil.getXmlConfigCacheKeyValue(NcqsConfigConstant.NCQS_CONF_NODE, NcqsConfigConstant.NCQS_ISSR_ID));
        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡支付退款服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }
        RefundAcqResponse response = new RefundAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }

    @Override
    public TransStatQueryAcqResponse transStatQuery(TransStatQueryAcqRequest request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        ConvertUtil.convertInput(request);
        ConvertUtil.convertInput(request.getRiskInfo());
        /* 设置银联无卡快捷的交易码，并调用银联客户端服务 */
        Schedule schedule = new Schedule();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, "3101");
        xmlTreeUtil.setXmlTreeStringValue(NcqsTreeNodeConstant.NCQS_TRX_TYP, "3101");
        int iReturnCode = schedule.callService(NcqsServiceConstant.NCQS_CLIENT_SERVICE, 0);

        /* 恢复原交易码 */
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.TXN_NUM, origTxnType);
        if (0 != iReturnCode) {
            rglog.error("调用银联无卡支付交易状态查询服务失败，iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), RespCodeEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
        }

        TransStatQueryAcqResponse response = new TransStatQueryAcqResponse();
        ConvertUtil.convertOutput(response);
        return response;
    }
}
